﻿/************************************************************************
 * author:漠然 2013年7月12日4:25:15
 * **********************************************************************/

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;

namespace Mrsoft.Update.Common
{
    /// <summary>
    /// Http下载类
    /// </summary>
    public static class WebEngine
    {

        private static readonly Dictionary<string, IPAddress> TemDns = new Dictionary<string, IPAddress>();

        public static string DownloadString(string url) {
            //DnsEndPoint dns = new DnsEndPoint();
            //将url补全
            url = !url.StartsWith("http://") ? string.Format("http://{0}", url) : url;
            return DownloadString(new Uri(url));
        }

        public static string DownloadString(Uri uri) {
            //TimeMeter tt = new TimeMeter();
            //tt.Start();
            string result;
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try {
                var ip = GetIp(uri.DnsSafeHost);
                if (socket.LocalEndPoint == null)
                    socket.Connect(ip, uri.Port);
                //tt.Show("连接socket");
                using (var ns = new NetworkStream(socket)) {
                    ns.Write("GET {0} HTTP/1.1\r\nUser-agent:MrEngine/1.0\r\nHOST:{1}\r\n\r\n", uri.PathAndQuery, uri.Host);
                    //tt.Show("send");
                    using (var ms = new MemoryStream()) {
                        var encoding = ns.GetResponse(ms);
                        //tt.Show("返回数据完成");
                        result = encoding.GetString(ms.ToArray());
                    }
                }
            }
            catch (Exception ex) {
                result = ex.Message;
            }
            socket.Close();
            //tt.Show("OVER___");
            //Console.WriteLine("调试输出网页内容{0}", result);
            return result;
        }

        private static IPAddress GetIp(string host) {
            host = host.ToLower();
            IPAddress result;
            var conf = new Config<string>("./ver.conf", "host", "180.149.131.99");

            if (!TemDns.TryGetValue(host, out result)) {
                try {
                    var addrList = Dns.GetHostAddresses(host);
                    result = addrList[0];
                    TemDns.Add(host, result);
                    if (host.ToLower().EndsWith(".duapp.com")) {
                        conf.Value = result.ToString();
                    }
                }
                catch {
                    Console.WriteLine(IPAddress.TryParse(conf.Value, out result));
                    if (!host.ToLower().EndsWith(".duapp.com")
                        && !IPAddress.TryParse(conf.Value, out result)) {
                        throw new Exception("DNS解析失败");
                    }
                    TemDns.Add(host, result);
                }
            }
            return result;
        }

        public static byte[] DownloadData(string url) {
            return DownloadData(new Uri(url));
        }

        public static byte[] DownloadData(Uri uri) {
            byte[] result;
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try {
                socket.Connect(GetIp(uri.DnsSafeHost), uri.Port);
                using (var ns = new NetworkStream(socket)) {
                    ns.Write("GET {0} HTTP/1.1\r\nUser-agent:MrEngine/1.0\r\nHOST:{1}\r\n\r\n", uri.PathAndQuery, uri.Host);
                    using (var ms = new MemoryStream()) {
                        ns.GetResponse(ms);
                        result = ms.ToArray();
                    }
                }
            }
            catch {
                result = null;
            }
            socket.Close();
            return result;
        }

        public static bool DownloadFile(string url, string fileName) {
            return DownloadFile(new Uri(url), fileName);
        }

        public static bool DownloadFile(Uri uri, string fileName) {
            var result = false;
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try {
                socket.Connect(GetIp(uri.DnsSafeHost), uri.Port);
                using (var ns = new NetworkStream(socket)) {
                    ns.Write("GET {0} HTTP/1.1\r\nUser-agent:MrEngine/1.0\r\nHOST:{1}\r\n\r\n", uri.PathAndQuery, uri.Host);
                    using (var fs = File.Create(fileName)) {
                        ns.GetResponse(fs);
                        fs.Close();
                    }
                }
                result = true;
            }
            catch //(Exception ex)
            {
                //Console.WriteLine();
            }
            socket.Close();
            return result;
        }

        public static string FormattInternetResultToXmlString(string ret) {
            if (!string.IsNullOrEmpty(ret)) {
                var start = ret.IndexOf("<", StringComparison.Ordinal);
                var stop = ret.LastIndexOf(">");
                if (start >= 0 && stop > start) {
                    return ret.Substring(start, stop - start + 1);
                }
            }
            return ret;
        }

        public static string Md5Encoding(string rawPass) {
            // 创建MD5类的默认实例：MD5CryptoServiceProvider
            MD5 md5 = MD5.Create();
            byte[] bs = Encoding.UTF8.GetBytes(rawPass);
            byte[] hs = md5.ComputeHash(bs);
            md5.Dispose();
            StringBuilder sb = new StringBuilder();
            foreach (var b in hs) {
                // 以十六进制格式格式化
                sb.Append(b.ToString("x2"));
            }
            return sb.ToString();
        }

    }


}
